package progetto.gruppo0506;

import java.util.ArrayList;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.RadioGroup.OnCheckedChangeListener;
import android.widget.Toast;
import android.widget.ZoomControls;

public class MappaActivity extends MapActivity {

	private MapView mapView;
	private MapController mapController;
	private RadioGroup rG;
	private ZoomControls zoomControls;

	private Localizzazione localizzazione;
	private ElencoPOI elenco;
	private PreferenzeUtente preferenze;
	private GooglePlaces google;

	private LinkedList<POI> fuoriItinerario;
	private LinkedList<POIItinerario> inItinerario;

	private ListView listaView;

	private Toast t;
	private Handler myHandler;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		/* Gestione XML */
		setContentView(R.layout.mappa);
		mapView = (MapView) findViewById(R.id.mapView);
		rG = (RadioGroup) findViewById(R.id.mappa_radio);

		// Otteniamo il riferimento al MapController
		mapController = mapView.getController();
	}

	@Override
	protected void onStart() {
		// TODO Auto-generated method stub
		super.onStart();

		// Gestione degli oggetti che sono stati creati in altre activity
		localizzazione = GestioneInterfaccia.getLocalizzazione();
		elenco = GestioneInterfaccia.getElenco();
		preferenze = GestioneInterfaccia.getPreferenze();
		google = GestioneInterfaccia.getGoogle();

		// Gestione LinkedList POI
		fuoriItinerario = elenco.estraiPOIFuoriItinerario();
		inItinerario = elenco.estraiPOIDaVisitare(google);

		// Gestione del percorso
		Percorso p = new Percorso(elenco.estraiPOIDaVisitare(google),
				localizzazione, google, preferenze);
		inItinerario = p.getElenco();
		
		Iterator<POIItinerario> it = inItinerario.iterator();
		while(it.hasNext())
			Log.i("Itinerario", it.next().getNome());

		// Gestione della mappa
		gestioneMappa();

		// Gestione dello Zoom
		gestioneZoom();

		/* Gestione dello Sliding Drower */
		gestioneSliding();

		/* Gestione della notifiche */
		notificaPermanenza();
		localizzazione.avviaNavigazione(inItinerario, fuoriItinerario, this);

		/* Visualizzazione del percorso */
		visualizzaPercorso();
	}

	/* Metodo privato per visualizzare il percorso */
	private void visualizzaPercorso() {
		List<Overlay> mapOverlays = mapView.getOverlays();

		Iterator<POIItinerario> it = inItinerario.iterator();

		// Posizione Corrente
		POIItinerario temp = it.next();
		Location partenza = new Location("Partenza");
		partenza.setLatitude(temp.getLatitudine());
		partenza.setLongitude(temp.getLongitudine());
		
		// Prima destinazione
		temp = it.next();
		Location destinazione = new Location("Destinazione");
		destinazione.setLatitude(temp.getLatitudine());
		destinazione.setLongitude(temp.getLongitudine());

		ArrayList<GeoPoint> pathPoints = DownloadPercorso.getPath(
				getBaseContext(), partenza, destinazione);

		if (pathPoints != null && pathPoints.size() > 1) {
			Log.i("Disegno", String.valueOf(pathPoints.size()));
			Iterator<GeoPoint> iterator = pathPoints.iterator();
			while (iterator.hasNext()) {
				GeoPoint temp1 = iterator.next();
				Log.i("Latitudine", String.valueOf(temp1.getLatitudeE6()));
				Log.i("Longitudine", String.valueOf(temp1.getLongitudeE6()));
			}

			mapOverlays.add(new DisegnaPercorso(pathPoints));
		}

		while (it.hasNext()) {
			partenza = destinazione;

			temp = it.next();
			destinazione = new Location("Destinazione");
			destinazione.setLatitude(temp.getLatitudine());
			destinazione.setLongitude(temp.getLongitudine());

			pathPoints = DownloadPercorso.getPath(getBaseContext(), partenza,
					destinazione);

			if (pathPoints != null && pathPoints.size() > 1) {
				Log.i("Disegno", String.valueOf(pathPoints.size()));
				Iterator<GeoPoint> iterator = pathPoints.iterator();
				while (iterator.hasNext()) {
					GeoPoint temp1 = iterator.next();
					Log.i("Latitudine", String.valueOf(temp1.getLatitudeE6()));
					Log.i("Longitudine", String.valueOf(temp1.getLongitudeE6()));
				}

				mapOverlays.add(new DisegnaPercorso(pathPoints));
			}
		}
	}

	/* Metodo privato utilizzato per la gestione delle notifiche */
	private void notificaPermanenza() {
		Iterator<POIItinerario> it = inItinerario.iterator();
		POIItinerario attuale;
		POIItinerario successivo;

		Message msg;
		Bundle b;

		t = Toast.makeText(this, "", Toast.LENGTH_LONG);
		myHandler = new Handler() {

			@Override
			public void handleMessage(Message msg) {
				t.setText("Se desideri seguire l'itinerario pianificato allora adesso recati a: "
						+ msg.getData().getString("successivo"));
				t.show();
			}

		};

		if (it.hasNext()) {
			attuale = it.next();

			if (it.hasNext()) {
				successivo = it.next();
				msg = myHandler.obtainMessage();
				b = new Bundle();
				b.putString("successivo", successivo.getNome());
				msg.setData(b);
				myHandler.sendMessageAtTime(msg, attuale.getFineVisita()
						.getTimeInMillis());

				while (it.hasNext()) {
					attuale = successivo;
					successivo = it.next();

					msg = myHandler.obtainMessage();
					b = new Bundle();
					b.putString("successivo", successivo.getNome());
					msg.setData(b);
					myHandler.sendMessageAtTime(msg, attuale.getFineVisita()
							.getTimeInMillis());
				}

			}
		}

	}

	/* Metodo privato utilizzato per la gestione della mappa */
	private void gestioneMappa() {
		mapView.setClickable(true);
		mapView.setBuiltInZoomControls(false);

		/* Imposta il centro della mappa con la posizione attuale dell'utente */
		mapController.setCenter(new GeoPoint((int) (inItinerario.getFirst()
				.getLatitudine() * 1E6), (int) (inItinerario.getFirst()
				.getLongitudine() * 1E6)));

		// Visualizzazione dei POI
		mapView.getOverlays()
				.add(new ElencoPOIOverLay(getResources().getDrawable(
						R.drawable.poi)));

		/* Gestione del tipo di mappa */
		rG.setOnCheckedChangeListener(new OnCheckedChangeListener() {

			public void onCheckedChanged(RadioGroup arg0, int buttonID) {
				// TODO Auto-generated method stub
				if (buttonID == R.id.mappa_radio_mappa) {
					mapView.setSatellite(false);
				} else {
					mapView.setSatellite(true);
				}
			}

		});
	}

	/* Metodo privato per la gestione dello Zoom */
	private void gestioneZoom() {
		zoomControls = (ZoomControls) findViewById(R.id.mappa_zoom);

		zoomControls.setOnZoomInClickListener(new OnClickListener() {
			public void onClick(View v) {
				mapView.getController().zoomIn();
			}
		});

		zoomControls.setOnZoomOutClickListener(new OnClickListener() {
			public void onClick(View v) {
				mapView.getController().zoomOut();
			}
		});

		int maxZoom = mapView.getMaxZoomLevel();
		if (preferenze.getTipoTrasporto().equalsIgnoreCase(
				PreferenzeUtente.AUTOVETTURA)) {
			mapController.setZoom(maxZoom - 5);
		} else {
			mapController.setZoom(maxZoom - 2);
		}
	}

	/* Metodo privato per la gestione dello Sliding Drawer */
	private void gestioneSliding() {
		listaView = (ListView) findViewById(R.id.mappa_sliding_elenco);
		listaView.setAdapter(new ArrayAdapter<POIItinerario>(this,
				R.layout.row_sliding, R.id.lista_poi_itinerario, inItinerario) {
			public View getView(int position, View convertView, ViewGroup parent) {
				POIItinerario item = getItem(position);

				LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
				View rowView = inflater.inflate(R.layout.row_sliding, null);

				TextView nameView = (TextView) rowView
						.findViewById(R.id.lista_poi_itinerario);
				nameView.setText(item.getNome());

				TextView orarioView = (TextView) rowView
						.findViewById(R.id.lista_orario_itinerario);
				orarioView.setText(""
						+ item.getInizioVisita().get(GregorianCalendar.HOUR_OF_DAY)
						+ " : "
						+ item.getInizioVisita().get(GregorianCalendar.MINUTE));
				
				return rowView;
			}
		});
	}

	/* Inner-Class utilizzata per la gestione degli OverLay */
	private class ElencoPOIOverLay extends ItemizedOverlay<OverlayItem> {

		private List<OverlayItem> elencoPOI = new LinkedList<OverlayItem>();
		private Drawable defaultMarker;

		public ElencoPOIOverLay(Drawable defaultMarker) {
			super(defaultMarker);
			// TODO Auto-generated constructor stub
			this.defaultMarker = defaultMarker;

			Iterator<POIItinerario> i = inItinerario.iterator();
			while (i.hasNext()) {
				POI poi = i.next();
				GeoPoint g = new GeoPoint((int) (poi.getLatitudine() * 1E6),
						(int) (poi.getLongitudine() * 1E6));

				Log.i("Latitudine POI", String.valueOf(g.getLatitudeE6()));
				Log.i("Longitudine POI", String.valueOf(g.getLongitudeE6()));

				OverlayItem overlay = new OverlayItem(g, poi.getNome(),
						poi.getNome());
				elencoPOI.add(overlay);
			}
			populate();
		}

		public void draw(Canvas canvas, MapView mapView, boolean shadow) {
			super.draw(canvas, mapView, shadow);
			boundCenterBottom(defaultMarker);
		}

		@Override
		protected OverlayItem createItem(int i) {
			// TODO Auto-generated method stub
			return elencoPOI.get(i);
		}

		@Override
		public int size() {
			// TODO Auto-generated method stub
			return elencoPOI.size();
		}
	}

	@Override
	protected boolean isRouteDisplayed() {
		// TODO Auto-generated method stub
		return false;
	}
}